home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / GPP257.ZIP / cplusinc / fix16.h < prev    next >
C/C++ Source or Header  |  1993-11-13  |  14KB  |  649 lines

  1. // This may look like C code, but it is really -*- C++ -*-
  2. /* 
  3. Copyright (C) 1988 Free Software Foundation
  4.     written by Kurt Baudendistel (gt-eedsp!baud@gatech.edu)
  5.     adapted for libg++ by Doug Lea (dl@rocky.oswego.edu)
  6.  
  7. This file is part of the GNU C++ Library.  This library is free
  8. software; you can redistribute it and/or modify it under the terms of
  9. the GNU Library General Public License as published by the Free
  10. Software Foundation; either version 2 of the License, or (at your
  11. option) any later version.  This library is distributed in the hope
  12. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  13. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  14. PURPOSE.  See the GNU Library General Public License for more details.
  15. You should have received a copy of the GNU Library General Public
  16. License along with this library; if not, write to the Free Software
  17. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19.  
  20. #ifndef _Fix16_h
  21. #ifdef __GNUG__
  22. #pragma interface
  23. #endif
  24. #define _Fix16_h 1
  25.  
  26. #include <stream.h>
  27. #include <std.h>
  28.  
  29. // constant definitions
  30.  
  31. #define Fix16_fs     ((double)((unsigned)(1 << 15)))
  32.  
  33. #define Fix16_msb    (1 << 15)
  34. #define Fix16_m_max    ((1 << 15) - 1)
  35. #define Fix16_m_min    ((short)(1 << 15))
  36.  
  37. #define Fix16_mult    Fix16_fs
  38. #define Fix16_div    (1./Fix16_fs)
  39. #define Fix16_max    (1. - .5/Fix16_fs)
  40. #define Fix16_min    (-1.)
  41.  
  42.  
  43. #define Fix32_fs     ((double)((unsigned long)(1 << 31)))
  44.  
  45. #define Fix32_msb    ((unsigned long)(1 << 31))
  46. #define Fix32_m_max    ((long)((1 << 31) - 1))
  47. #define Fix32_m_min    ((long)(1 << 31))
  48.  
  49. #define Fix32_mult    Fix32_fs
  50. #define Fix32_div    (1./Fix32_fs)
  51. #define Fix32_max    (1. - .5/Fix32_fs)
  52. #define Fix32_min    (-1.)
  53.  
  54.  
  55. //
  56. // Fix16    class: 16-bit Fixed point data type
  57. //
  58. //    consists of a 16-bit mantissa (sign bit & 15 data bits).
  59. //
  60.  
  61. class Fix16 
  62.   friend class          Fix32;
  63.  
  64.   short                 m;
  65.  
  66.   short                 round(double d);
  67.   short                 assign(double d);
  68.                         Fix16(short i);
  69.                         Fix16(int i);
  70.  
  71.          operator       double() const;
  72.  
  73.  
  74. public:
  75.                         Fix16();
  76.                         Fix16(const Fix16&  f);
  77.                         Fix16(double d);
  78.                         Fix16(const Fix32& f);
  79.  
  80.                         ~Fix16();
  81.  
  82.   Fix16&                operator=(const Fix16&  f);
  83.   Fix16&                operator=(double d);
  84.   Fix16&                operator=(const Fix32& f);
  85.  
  86.   friend short&         mantissa(Fix16&  f);
  87.   friend const short&   mantissa(const Fix16&  f);
  88.   friend double         value(const Fix16&  f);
  89.  
  90.   Fix16                 operator +  () const;
  91.   Fix16                 operator -  () const;
  92.  
  93.   friend Fix16          operator +  (const Fix16&  f, const Fix16&  g);
  94.   friend Fix16          operator -  (const Fix16&  f, const Fix16&  g);
  95.   friend Fix32          operator *  (const Fix16&  f, const Fix16&  g);
  96.   friend Fix16          operator /  (const Fix16&  f, const Fix16&  g);
  97.   friend Fix16          operator << (const Fix16&  f, int b);
  98.   friend Fix16          operator >> (const Fix16&  f, int b);
  99.  
  100.   Fix16&                operator += (const Fix16&  f);
  101.   Fix16&                operator -= (const Fix16&  f);
  102.   Fix16&                operator *= (const Fix16& );
  103.   Fix16&                operator /= (const Fix16&  f);
  104.   
  105.   Fix16&                operator <<=(int b);
  106.   Fix16&                operator >>=(int b);
  107.  
  108.   friend int            operator == (const Fix16&  f, const Fix16&  g);
  109.   friend int            operator != (const Fix16&  f, const Fix16&  g);
  110.   friend int            operator >= (const Fix16&  f, const Fix16&  g);
  111.   friend int            operator <= (const Fix16&  f, const Fix16&  g);
  112.   friend int            operator >  (const Fix16&  f, const Fix16&  g);
  113.   friend int            operator <  (const Fix16&  f, const Fix16&  g);
  114.  
  115.   friend istream&       operator >> (istream& s, Fix16&  f);
  116.   friend ostream&       operator << (ostream& s, const Fix16&  f);
  117.  
  118.   void                  overflow(short&) const;
  119.   void                  range_error(short&) const;
  120.  
  121.   friend Fix16          operator *  (const Fix16&  f, int g);
  122.   friend Fix16          operator *  (int g, const Fix16&  f);
  123.   Fix16&                operator *= (int g);
  124. };
  125.  
  126.  
  127. //
  128. // Fix32 class: 32-bit Fixed point data type
  129. //
  130. //    consists of a 32-bit mantissa (sign bit & 31 data bits).
  131. //
  132.  
  133. class Fix32 
  134.   friend class         Fix16;
  135.  
  136.   long                 m;
  137.  
  138.   long                 round(double d);
  139.   long                 assign(double d);
  140.  
  141.                        Fix32(long i);
  142.                        operator double() const;
  143.  
  144.  
  145. public:
  146.                        Fix32();
  147.                        Fix32(const Fix32& f);
  148.                        Fix32(const Fix16&  f);
  149.                        Fix32(double d);
  150.                        ~Fix32();
  151.  
  152.   Fix32&               operator =  (const Fix32& f);
  153.   Fix32&               operator =  (const Fix16&  f);
  154.   Fix32&               operator =  (double d);
  155.  
  156.   friend long&         mantissa(Fix32& f);
  157.   friend const long&   mantissa(const Fix32& f);
  158.   friend double        value(const Fix32& f);
  159.  
  160.   Fix32                operator +  () const;
  161.   Fix32                operator -  () const;
  162.  
  163.   friend Fix32         operator +  (const Fix32& f, const Fix32& g);
  164.   friend Fix32         operator -  (const Fix32& f, const Fix32& g);
  165.   friend Fix32         operator *  (const Fix32& f, const Fix32& g);
  166.   friend Fix32         operator /  (const Fix32& f, const Fix32& g);
  167.   friend Fix32         operator << (const Fix32& f, int b);
  168.   friend Fix32         operator >> (const Fix32& f, int b);
  169.  
  170.   friend Fix32         operator *  (const Fix16&  f, const Fix16&  g);
  171.  
  172.   Fix32&               operator += (const Fix32& f);
  173.   Fix32&               operator -= (const Fix32& f);
  174.   Fix32&               operator *= (const Fix32& f);
  175.   Fix32&               operator /= (const Fix32& f);
  176.   Fix32&               operator <<=(int b);
  177.   Fix32&               operator >>=(int b);
  178.  
  179.   friend int           operator == (const Fix32& f, const Fix32& g);
  180.   friend int           operator != (const Fix32& f, const Fix32& g);
  181.   friend int           operator >= (const Fix32& f, const Fix32& g);
  182.   friend int           operator <= (const Fix32& f, const Fix32& g);
  183.   friend int           operator >  (const Fix32& f, const Fix32& g);
  184.   friend int           operator <  (const Fix32& f, const Fix32& g);
  185.  
  186.   friend istream&      operator >> (istream& s, Fix32& f);
  187.   friend ostream&      operator << (ostream& s, const Fix32& f);
  188.  
  189.   void                 overflow(long& i) const;
  190.   void                 range_error(long& i) const;
  191.  
  192.   friend Fix32          operator *  (const Fix32&  f, int g);
  193.   friend Fix32          operator *  (int g, const Fix32&  f);
  194.   Fix32&                operator *= (int g);
  195. };
  196.  
  197. // active error handler declarations
  198.  
  199. typedef void (*Fix16_peh)(short&);
  200. typedef void (*Fix32_peh)(long&);
  201.  
  202. extern Fix16_peh Fix16_overflow_handler;
  203. extern Fix32_peh Fix32_overflow_handler;
  204.  
  205. extern Fix16_peh Fix16_range_error_handler;
  206. extern Fix32_peh Fix32_range_error_handler;
  207.  
  208. #if defined(SHORT_NAMES) || defined(VMS)
  209. #define    set_overflow_handler    sohndl
  210. #define set_range_error_handler    srnghdl
  211. #endif
  212.  
  213.  
  214. // error handler declarations
  215.  
  216. extern Fix16_peh set_Fix16_overflow_handler(Fix16_peh);
  217. extern Fix32_peh set_Fix32_overflow_handler(Fix32_peh);
  218. extern void set_overflow_handler(Fix16_peh, Fix32_peh);
  219.  
  220. extern Fix16_peh set_Fix16_range_error_handler(Fix16_peh);
  221. extern Fix32_peh set_Fix32_range_error_handler(Fix32_peh);
  222. extern void set_range_error_handler(Fix16_peh, Fix32_peh);
  223.  
  224. extern void
  225.   Fix16_ignore(short&),
  226.   Fix16_overflow_saturate(short&),
  227.   Fix16_overflow_warning_saturate(short&),
  228.   Fix16_warning(short&),
  229.   Fix16_abort(short&);
  230.  
  231. extern void
  232.   Fix32_ignore(long&),
  233.   Fix32_overflow_saturate(long&),
  234.   Fix32_overflow_warning_saturate(long&),
  235.   Fix32_warning(long&),
  236.   Fix32_abort(long&);
  237.  
  238.  
  239. inline Fix16::~Fix16() {}
  240.  
  241. inline short Fix16::round(double d)
  242.   return short( (d >= 0)? d + 0.5 : d - 0.5); 
  243. }
  244.  
  245. inline Fix16::Fix16(short i)        
  246.   m = i; 
  247. }
  248.  
  249. inline Fix16::Fix16(int i)        
  250.   m = i; 
  251. }
  252.  
  253. inline Fix16::operator double() const 
  254.   return  Fix16_div * m; 
  255. }
  256.  
  257. inline Fix16::Fix16()                 
  258.   m = 0; 
  259. }
  260.  
  261. inline Fix16::Fix16(const Fix16&  f)        
  262.   m = f.m; 
  263. }
  264.  
  265. inline Fix16::Fix16(double d)        
  266. {
  267.   m = assign(d);
  268. }
  269.  
  270.  
  271. inline Fix16&  Fix16::operator=(const Fix16&  f)    
  272.   m = f.m; 
  273.   return *this; 
  274. }
  275.  
  276. inline Fix16&  Fix16::operator=(double d) 
  277.   m = assign(d); 
  278.   return *this; 
  279. }
  280.  
  281.  
  282. inline Fix32::Fix32()                
  283.   m = 0;
  284. }
  285.  
  286. inline Fix32::Fix32(long i)        
  287.   m = i;
  288. }
  289.  
  290. inline Fix32:: operator double() const        
  291.   return Fix32_div * m;
  292. }
  293.  
  294.  
  295. inline Fix32::Fix32(const Fix32& f)        
  296.   m = f.m;
  297. }
  298.  
  299. inline Fix32::Fix32(const Fix16&  f)    
  300.   m = long(f.m) << 16;
  301. }
  302.  
  303. inline Fix32::Fix32(double d)        
  304.   m = assign(d);
  305. }
  306.  
  307. inline Fix16::Fix16(const Fix32& f)        
  308.   m = f.m >> 16; 
  309. }
  310.  
  311.  
  312. inline Fix16&  Fix16::operator=(const Fix32& f)
  313.   m = f.m >> 16; 
  314.   return *this; 
  315. }
  316.  
  317. inline Fix32& Fix32::operator=(const Fix32& f)    
  318.   m = f.m;
  319.   return *this; 
  320. }
  321.  
  322. inline Fix32& Fix32::operator=(const Fix16&  f)    
  323.   m = long(f.m) << 16;
  324.   return *this;
  325. }
  326.  
  327. inline Fix32& Fix32::operator=(double d)    
  328.   m = assign(d);
  329.   return *this; 
  330. }
  331.  
  332. inline short& mantissa(Fix16&  f)    
  333.   return f.m; 
  334. }
  335.  
  336. inline const short& mantissa(const Fix16&  f)    
  337.   return f.m; 
  338. }
  339.  
  340. inline double value(const Fix16&  f)        
  341.   return double(f); 
  342. }
  343.  
  344. inline Fix16 Fix16::operator+() const        
  345.   return m; 
  346. }
  347.  
  348. inline Fix16 Fix16::operator-() const    
  349.   return -m; 
  350. }
  351.  
  352. inline Fix16 operator+(const Fix16&  f, const Fix16&  g) 
  353. {
  354.   short sum = f.m + g.m;
  355.   if ( (f.m ^ sum) & (g.m ^ sum) & Fix16_msb )
  356.     f.overflow(sum);
  357.   return sum;
  358. }
  359.  
  360. inline Fix16 operator-(const Fix16&  f, const Fix16&  g) 
  361. {
  362.   short sum = f.m - g.m;
  363.   if ( (f.m ^ sum) & (-g.m ^ sum) & Fix16_msb )
  364.     f.overflow(sum);
  365.   return sum;
  366. }
  367.  
  368. inline Fix32 operator*(const Fix16&  f, const Fix16&  g)
  369.   return Fix32( long( long(f.m) * long(g.m) << 1)); 
  370. }
  371.  
  372. inline Fix16 operator<<(const Fix16& a, int b)     
  373.   return a.m << b; 
  374. }
  375.  
  376. inline Fix16 operator>>(const Fix16& a, int b)     
  377.   return a.m >> b; 
  378. }
  379.  
  380. inline  Fix16&  Fix16:: operator+=(const Fix16&  f)
  381.   return *this = *this + f; 
  382. }
  383.  
  384. inline Fix16&  Fix16:: operator-=(const Fix16&  f)     
  385.   return *this = *this - f; 
  386. }
  387.  
  388. inline Fix16& Fix16::operator*=(const Fix16& f)     
  389.   return *this = *this * f; 
  390. }
  391.  
  392. inline Fix16&  Fix16:: operator/=(const Fix16&  f)     
  393.   return *this = *this / f; 
  394. }
  395.  
  396. inline Fix16&  Fix16:: operator<<=(int b)    
  397.   return *this = *this << b;
  398. }
  399.  
  400. inline Fix16&  Fix16:: operator>>=(int b)    
  401.   return *this = *this >> b;
  402. }
  403.  
  404. inline int operator==(const Fix16&  f, const Fix16&  g)    
  405.   return f.m == g.m;
  406. }
  407.  
  408. inline int operator!=(const Fix16&  f, const Fix16&  g)    
  409.   return f.m != g.m;
  410. }
  411.  
  412. inline int operator>=(const Fix16&  f, const Fix16&  g)    
  413.   return f.m >= g.m;
  414. }
  415.  
  416. inline int operator<=(const Fix16&  f, const Fix16&  g)    
  417.   return f.m <= g.m;
  418. }
  419.  
  420. inline int operator>(const Fix16&  f, const Fix16&  g)    
  421.   return f.m > g.m;
  422. }
  423.  
  424. inline int operator<(const Fix16&  f, const Fix16&  g)    
  425.   return f.m < g.m;
  426. }
  427.  
  428. inline istream&  operator>>(istream& s, Fix16&  f)
  429.   double d;
  430.   s >> d; 
  431.   f = d; 
  432.   return s; 
  433. }
  434.  
  435. inline ostream&  operator<<(ostream& s, const Fix16&  f)
  436.   return s << double(f);
  437. }
  438.  
  439.  
  440. inline Fix16 operator*(const Fix16&  f, int g)
  441. {
  442.   return Fix16(short(f.m * g));
  443. }
  444.  
  445. inline Fix16 operator*(int g, const Fix16&  f)
  446. {
  447.   return f * g;
  448. }
  449.  
  450.  
  451. inline Fix16& Fix16::operator*=(int g)
  452. {
  453.   return *this = *this * g;
  454. }
  455.  
  456. inline Fix32::~Fix32() {}
  457.  
  458. inline long Fix32::round(double d)
  459.   return long( (d >= 0)? d + 0.5 : d - 0.5);
  460. }
  461.  
  462. inline long& mantissa(Fix32& f)    
  463.   return f.m;
  464. }
  465.  
  466. inline const long& mantissa(const Fix32& f)    
  467.   return f.m;
  468. }
  469.  
  470. inline double value(const Fix32& f)        
  471.   return double(f);
  472. }
  473.  
  474. inline Fix32 Fix32::operator+() const
  475.   return m;
  476. }
  477.  
  478. inline Fix32 Fix32::operator-() const        
  479.   return -m;
  480. }
  481.  
  482. inline Fix32 operator+(const Fix32& f, const Fix32& g) 
  483. {
  484.   long sum = f.m + g.m;
  485.   if ( (f.m ^ sum) & (g.m ^ sum) & Fix32_msb )
  486.     f.overflow(sum);
  487.   return sum;
  488. }
  489.  
  490. inline Fix32 operator-(const Fix32& f, const Fix32& g) 
  491. {
  492.   long sum = f.m - g.m;
  493.   if ( (f.m ^ sum) & (-g.m ^ sum) & Fix32_msb )
  494.     f.overflow(sum);
  495.   return sum;
  496. }
  497.  
  498. inline Fix32 operator<<(const Fix32& a, int b)     
  499.   return a.m << b;
  500. }
  501.  
  502. inline Fix32 operator>>(const Fix32& a, int b)     
  503.   return a.m >> b;
  504. }
  505.  
  506. inline Fix32& Fix32::operator+=(const Fix32& f)     
  507.   return *this = *this + f;
  508. }
  509.  
  510. inline Fix32& Fix32::operator-=(const Fix32& f)     
  511.   return *this = *this - f;
  512. }
  513.  
  514. inline Fix32& Fix32::operator*=(const Fix32& f)     
  515.   return *this = *this * f;
  516. }
  517.  
  518. inline Fix32& Fix32::operator/=(const Fix32& f)     
  519.   return *this = *this / f;
  520. }
  521.  
  522.  
  523. inline Fix32& Fix32::operator<<=(int b)    
  524.   return *this = *this << b;
  525. }
  526.  
  527. inline Fix32& Fix32::operator>>=(int b)    
  528.   return *this = *this >> b;
  529. }
  530.  
  531. inline int operator==(const Fix32& f, const Fix32& g)    
  532.   return f.m == g.m;
  533. }
  534.  
  535. inline int operator!=(const Fix32& f, const Fix32& g)    
  536.   return f.m != g.m;
  537. }
  538.  
  539. inline int operator>=(const Fix32& f, const Fix32& g)    
  540.   return f.m >= g.m;
  541. }
  542.  
  543. inline int operator<=(const Fix32& f, const Fix32& g)    
  544.   return f.m <= g.m;
  545. }
  546.  
  547. inline int operator>(const Fix32& f, const Fix32& g)    
  548.   return f.m > g.m;
  549. }
  550.  
  551. inline int operator<(const Fix32& f, const Fix32& g)    
  552.   return f.m < g.m;
  553. }
  554.  
  555. inline istream& operator>>(istream& s, Fix32& f)
  556.   double d;
  557.   s >> d; 
  558.   f = d; 
  559.   return s; 
  560. }
  561.  
  562. inline ostream& operator<<(ostream& s, const Fix32& f)
  563.   return s << double(f);
  564. }
  565.  
  566. inline Fix32 operator*(const Fix32&  f, int g)
  567. {
  568.   return Fix32(long(f.m * g));
  569. }
  570.  
  571. inline Fix32 operator*(int g, const Fix32&  f)
  572. {
  573.   return f * g;
  574. }
  575.  
  576.  
  577.  
  578. inline Fix32& Fix32::operator*=(int g)
  579. {
  580.   return *this = *this * g;
  581. }
  582.  
  583. #endif
  584.